var LT = LT || {};

(function($, LT) {
    'use strict';

    // Контроллер страницы
    LT.PageLanging = function() {
        var CLASS_FORM_LOADING = 'signup__form_loading',
                CLASS_FIELD_ERROR = 'signup__field_error';

        this.$event = $(this);

        this._forms = {
            'registration': new LT.RegistrationForm(this),
            'login': new LT.LoginForm(this)
        };
        this._switcher = new LT.FormsSwitcher(this);

        this.init = function() {
            this.$event.on('_switcher:switchStart', function() {
                $('.signup__field_error').removeClass('signup__field_error');
            });

            $(document.body).on('click', '.js__need-auth', this.needAuthAlert.bind(this));
        };

        this.setStateLoading = function($form) {
            $form.addClass(CLASS_FORM_LOADING);
        };

        this.removeStateLoading = function($form) {
            $form.removeClass(CLASS_FORM_LOADING);
        };

        this.needAuthAlert = function() {
            this._forms[this._switcher.currentForm].submit();
        };

        this.fieldError = function(field, msg, onFree) {
            var
                    $field = $(field),
                    isSelect = $field.hasClass('custom-select-input'),
                    $wrap = $field.closest('.signup__field'),
                    errorBubbleClass = 'in-error-bubble',
                    $error = $wrap.find('.' + errorBubbleClass),
                    free = function() {
                $wrap.removeClass(CLASS_FIELD_ERROR);
                $error && $error.remove();
                onFree && onFree();
            };
            $wrap.addClass(CLASS_FIELD_ERROR);

            if (msg) {
                if (!$error.length) {
                    $error = $('<span class="' + errorBubbleClass + '" />').appendTo($wrap);
                }
                $error
                        .html(msg + '<span/>')
                        .fadeIn(100)
                        .click(free);
            }
            else if ($error.length) {
                $error.empty();
            }
            $field.one('keydown.signup click.signup liszt:showing_dropdown', free);
        };

        this.init();
    };

    // Форма регистрации
    LT.RegistrationForm = function(PageController) {
        var $content = $('.registration-form:first'),
                $select, $country, $city, $form, $cityDisabled,
                html,
                sendProcess = false;

        if (!$content.length) {
            return false;
        }

        this.init = function() {
            $select = $('.input-chosen', $content);
            $country = $select.filter('[name=country]');
            $city = $select.filter('[name=city]');
            $cityDisabled = $city.siblings('.city-disabled');
            $form = $('form:first', $content).on('submit', this.submit.bind(this));


            $select.not($country).each(function() {
                var $this = $(this),
                        _width = $this.data('width') || $this.width();

                $this.chosen({
                    width: _width
                });
            });

            $country
                    .chosen({
                width: ($country.data('width') || $country.width())
            })
                    .change(function() {
                $cityDisabled.show();
                LT.GeoDictionary.getListCities({
                    name: 'city',
                    parent: this.value,
                    success: function(res) {
                        html = [];
                        res.forEach(function(obj, i) {
                            html.push('<option value="', obj.value, '">', (obj.value ? obj.text : ''), '</option>');
                        });
                        $city
                                .html(html.join(''))
                                .trigger("liszt:updated");
                        $cityDisabled.hide();
                    }
                });
            });
        };

        this.submit = function() {
            this._validateForm() && this._send();
            return false;
        };

        this._validateForm = function() {
            var
                    errorFields = [],
                    formData = $form.serializeObject(),
                    error = function(name, msg) {
                var $field = $form.find(h('[name=', name, ']'));
                errorFields.push($field);
                PageController.fieldError($field, msg);
            },
                    birthDate,
                    minPossibleBirthDate = new Date().offsetYears(-18);

            if (!formData.name) {
                error('name', LT.t('signinErrorNameEmpty'));
            }
            if (formData.sex === '' || !formData.sex) {
                error('sex', LT.t('signinErrorSex'));
            }
            if (!formData.birth_day) {
                error('birth_day', LT.t('signinErrorBirthDayEmpty'));
            }
            if (!formData.birth_month) {
                error('birth_month', LT.t('signinErrorBirthMonthEmpty'));
            }
            if (!formData.birth_year) {
                error('birth_year', LT.t('signinErrorBirthYearEmpty'));
            }
            if (
                    formData.birth_year &&
                    formData.birth_month &&
                    formData.birth_day &&
                    (birthDate = new Date(formData.birth_year, formData.birth_month - 1, formData.birth_day)) &&
                    LT.is_valid_date(birthDate) &&
                    birthDate.greater(minPossibleBirthDate)
                    ) {
                error('birth_year', LT.t('signinErrorTooYoung'));
            }

            if (!formData.country && !$country.prop('disabled')) {
                error('country', LT.t('signinCountryEmptyError'));
            }

            if (!formData.city) {
                error('city', LT.t('signinCityEmptyError'));
            }

            if (!formData.email) {
                error('email', LT.t('signinEmailEmptyError'));
            }
            else if (!LT.isEmail(formData.email)) {
                error('email', LT.t('signinEmailMaskError'));
            }

            if (!formData.password) {
                error('password', LT.t('signinPasswordEmptyError'));
            }
            else if (String(formData.password).length < 5) {
                error('password', LT.t('signinPasswordMinLengthError'));
            }
            if (errorFields[0]) {
                errorFields[0].select();
            }
            return !errorFields.length;
        };

        this._send = function() {
            if (sendProcess) {
                return false;
            }

            sendProcess = true;

            PageController.setStateLoading($form);

            var reqData = {
                ajax: 'signup-form'
            },
            hasErrors = false,
                    formData = $form.serializeObject();

            $.each(formData, function(key, value) {
                reqData['Users[' + key + ']'] = value;
            });

            $.ajax({
                quite: true,
                type: 'POST',
                dataType: 'json',
                data: reqData,
                url: '/users/register',
                success: function(res) {
                    var unknownErrors = [];
                    if ($.isPlainObject(res)) {
                        if (res.age) {
                            res.birth_month = res.age;
                            delete res.age;
                        }
                        if (!res.status) {
                            $.each(res, function(name, msg) {
                                var
                                        m = String(name).match(/^Users_(.+)$/),
                                        $field = $form.find('[name="' + name + '"]');
                                if (m && m[1]) {
                                    name = m[1];
                                }
                                if (!$field.length) {
                                    unknownErrors.push(msg);
                                    return;
                                }
                                PageController.fieldError(
                                        $field,
                                        $.isArray(msg) ? msg[0] : msg.toString()
                                        );
                                hasErrors = true;
                            });

                            if (unknownErrors[0]) {
                                /* Displaying unknown error (first of them) at email field */
                                PageController.fieldError(
                                        $form.find('[name="email"]'),
                                        $.isArray(unknownErrors[0])
                                        ? unknownErrors[0][0]
                                        : unknownErrors[0].toString()
                                        );
                                hasErrors = true;
                            }
                        }
                    }
                    if (!hasErrors) {
                        /* Signup succeeded, so just refresh page */
                        window.location = '/users/view/' + res.id + '?reg_ok=1';
                    }
                },
                complete: function() {
                    sendProcess = false;
                    if (hasErrors) {
                        PageController.removeStateLoading($form);
                    }
                }
            });
        };

        this.init();
    };

    // Login form
    LT.LoginForm = function(PageController) {
        var $content = $('.login-form:first'),
                $form,
                sendProcess = false;

        if (!$content.length) {
            return false;
        }

        this.init = function() {
            $form = $('form:first', $content).on('submit', this.submit.bind(this));
        };

        this.submit = function() {
            this._validateForm() && this._send();
            return false;
        };

        this._validateForm = function() {
            var
                    errorFields = [],
                    formData = $form.serializeObject(),
                    error = function(name, msg) {
                var $field = $form.find('[name="' + name + '"]');
                errorFields.push($field);
                PageController.fieldError($field, msg);
            };
            if (!formData['LoginForm[email]']) {
                error('LoginForm[email]', LT.t('signinEmailEmptyError'));
            }
            else if (!LT.isEmail(formData['LoginForm[email]'])) {
                error('LoginForm[email]', LT.t('signinEmailMaskError'));
            }

            if (!formData['LoginForm[password]']) {
                error('LoginForm[password]', LT.t('signinPasswordEmptyError'));
            }

            if (errorFields[0]) {
                errorFields[0].select();
            }
            return !errorFields.length;
        };

        this._send = function() {
            if (sendProcess) {
                return false;
            }

            sendProcess = true;

            PageController.setStateLoading($form);

            var formData = $form.serializeObject(),
                    hasErrors = false;
            formData.ajax = 'login-form';

            $.ajax({
                quite: true,
                type: 'POST',
                dataType: 'json',
                data: formData,
                url: '/site/login',
                success: function(res) {
                    if (res) {
                        if (res[ 'LoginForm_password' ]) {
                            PageController.fieldError(
                                    $form.find('[name="LoginForm[email]"]'),
                                    '',
                                    function() {
                                        $form.find('[name="LoginForm[password]"]').click();
                                    }
                            );
                            PageController.fieldError(
                                    $form.find(h('[name="LoginForm[password]"]')),
                                    res['LoginForm_password'],
                                    function() {
                                        $form.find(h('[name="LoginForm[email]"]')).click()
                                    }
                            );
                            hasErrors = true;
                        } else if (res['LoginForm_visible']) {
                            PageController.fieldError(
                                    $form.find(h('[name="LoginForm[email]"]')),
                                    res['LoginForm_visible'],
                                    function() {
                                        $form.find(h('[name="LoginForm[password]"]')).click();
                                    }
                            );
                            hasErrors = true;
                        }
                        if (!hasErrors) {
                            window.location.reload(false);
                        }
                    }
                },
                complete: function() {
                    sendProcess = false;
                    if (hasErrors) {
                        PageController.removeStateLoading($form);
                    }
                }
            });
        };


        this.init();
    };

    LT.FormsSwitcher = function(PageController) {
        var $content = $('.signup:first'),
                $buttonSwitch,
                $buttonSwitchText,
                buttonLabels = {
            'login': LT.t('signinAction'),
            'registration': LT.t('signupAction')
        },
        FacebookLabels = {
            'login': LT.t('loginVia'),
            'registration': LT.t('registerVia')
        },
        VkontakteLabels = {
            'login': LT.t('loginViaVkontakte'),
            'registration': LT.t('registerViaVkontakte')
        },
        $registration,
                $login,
                $facebookButtonText,
                $vkontakteButtonText,
                self = this;

        if (!$content.length) {
            return false;
        }

        this.currentForm = null;

        this.init = function() {
            $buttonSwitch = $content.parent().find('.n-slide-button:first');
            $buttonSwitch.on('click', function() {
                this.switchPane();
            }.bind(this));

            $registration = $content.find('.registration-form:first');
            $login = $content.find('.login-form:first');

            $buttonSwitchText = $buttonSwitch.children('ins');

            $facebookButtonText = $('.in-button_facebook__button:first');
            $vkontakteButtonText = $('.in-button_vkontakte__button:first');
            this.actualizeForm();

            if (location.hash == '#signup') {
                this.switchFocus('registration');
            }
        };

        this.actualizeForm = function() {
            this.currentForm = ($login.is(':visible') ? 'login' : 'registration');
            $facebookButtonText.text(FacebookLabels[this.currentForm]);
            $vkontakteButtonText.text(VkontakteLabels[this.currentForm]);
        };

        this.switchPane = function(form) {
            this.actualizeForm();
            $(PageController).trigger('_switcher:switchStart', {currentForm: this.currentForm});
            if (form === this.currentForm || form && !buttonLabels[form]) {
                return;
            }
            $buttonSwitchText.text(buttonLabels[this.currentForm]);

            if (this.currentForm === 'login') {
                $login.slideUp(250, function() {
                    $registration.slideDown(250, this.switchEnd);
                }.bind(this));
            } else {
                $registration.slideUp(250, function() {
                    $login.slideDown(250, this.switchEnd);
                }.bind(this));
            }
        };

        this.switchEnd = function() {
            self.actualizeForm();
            $(PageController).trigger('_switcher:switch', {currentForm: this.currentForm});
        };

        this.switchFocus = function(form) {
            $('html').animate({
                scrollTop: top
            }, {
                duration: 500,
                easing: 'swing'
            });
            this.switchPane(form);
        };

        this.init();
    };
}(window.jQuery, LT));
